package com.npr.MyFilter;

import com.npr.entity.LoginTicket;
import com.npr.entity.User;
import com.npr.service.UserService;
import com.npr.util.CookieUtil;
import com.npr.util.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

@Component
public class LoginTicketFilter extends OncePerRequestFilter {
    @Autowired
    private UserService userService;
    @Autowired
    private HostHolder hostHolder;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //放行静态资源
        String spath = request.getServletPath();
        String[] urls = {".js", ".css", ".ico", ".jpg", ".png"};
        boolean flag = false;
        for (String str : urls) {
            if (spath.indexOf(str) != -1) {
                flag = true;
                break;
            }
        }
        if (flag) {
            filterChain.doFilter(request,response);
        } else {
            //从cookie中获取凭证
            String ticket = CookieUtil.getValue(request, "ticket");
            if (ticket != null) {
                //查询凭证
                LoginTicket loginTicket = userService.findLoginTicket(ticket);
                //检查凭证是否有效

                if (loginTicket != null && loginTicket.getStatus() == 0 && loginTicket.getExpired().after(new Date())) {
                    //根据凭证查询用户
                    User user = userService.findUserById(loginTicket.getUserId());
                    //在本次请求中持有用户
                    hostHolder.setUser(user);
                    //构建用户认证的结果，并存入SecurityContext,以便于Security进行授权
                    Authentication authentication = new UsernamePasswordAuthenticationToken(
                            user, user.getPassword(), userService.getAuthorities(user.getId())
                    );
                    SecurityContextHolder.setContext(new SecurityContextImpl(authentication));
                }
            }
            filterChain.doFilter(request, response);
        }
    }
}
